<template>
  <div class="col-12 padding-page">
    <div class="row justify-around no-padding">
      <div
        id="sampleBar"
        ref="sampleBarDom"
        class="no-margin col-3"
        style="height: 600px; min-width: 280px"
      />
      <div
        id="mnvBar"
        ref="mnvBarDom"
        class="no-margin col-3"
        style="height: 600px; min-width: 280px"
      />
      <div
        id="phenoBar"
        ref="phenoBarDom"
        class="no-margin col-3"
        style="height: 600px; min-width: 280px"
      />
      <div
        id="qtlBar"
        ref="qtlBarDom"
        class="no-margin col-3"
        style="height: 600px; min-width: 280px"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, computed, watch } from 'vue';
import { useSiteSettings } from 'src/stores/site_setting';
import { storeToRefs } from 'pinia';
import { getDataCounts } from 'boot/dataCount';

import * as echarts from 'echarts/core';
import {
  TooltipComponent,
  GridComponent,
  LegendComponent,
} from 'echarts/components';
import { BarChart } from 'echarts/charts';
import { SVGRenderer } from 'echarts/renderers';

// 导入主题
import darkTheme from 'src/css/echart_themes/dark.json';
import lightTheme from 'src/css/echart_themes/light.json';

import { qtlType } from 'src/interface/qtlType';

echarts.registerTheme('myDark', darkTheme);
echarts.registerTheme('myLight', lightTheme);
echarts.use([
  BarChart,
  SVGRenderer,
  TooltipComponent,
  GridComponent,
  LegendComponent,
]);

// 网站的状态
const siteSettingStore = useSiteSettings();
const siteSettingRef = storeToRefs(siteSettingStore);
const echart_theme = computed(() => {
  return siteSettingRef.dark.value ? 'myDark' : 'myLight';
});

// 组件参数
const cancerList = [
  'ACC',
  'BLCA',
  'BRCA',
  'CESC',
  'CHOL',
  'COAD',
  'DLBC',
  'ESCA',
  'GBM',
  'HNSC',
  'KICH',
  'KIRC',
  'KIRP',
  'LAML',
  'LGG',
  'LIHC',
  'LUAD',
  'LUSC',
  'MESO',
  'OV',
  'PAAD',
  'PCPG',
  'PRAD',
  'READ',
  'SARC',
  'SKCM',
  'STAD',
  'TGCT',
  'THCA',
  'THYM',
  'UCEC',
  'UCS',
  'UVM',
];

const dataStat = getDataCounts();

const common_bar_options = (xlabel: string) => {
  return {
    tooltip: {
      show: true,
    },
    grid: {
      top: 10,
      bottom: 60,
      left: 60,
      right: 90,
    },
    xAxis: {
      type: 'value',
      axisLabel: {
        rotate: 30,
      },
      axisTick: {
        alignWithLabel: true,
      },
      name: xlabel,
      nameLocation: 'middle',
      nameTextStyle: {
        padding: [30, 0, 0, 0],
        fontSize: 14,
      },
    },
    yAxis: {
      type: 'category',
      data: cancerList,
      inverse: true,
      axisLabel: {
        fontSize: 11,
      },
    },
  };
};

const sample_count_settings_generator = (
  name: string,
  xlabel: string,
  data: number[],
  color: 'blue'
) => {
  return {
    ...common_bar_options(xlabel),
    series: {
      id: name,
      type: 'bar',
      colorBy: 'series',
      label: {
        show: false,
        position: 'right',
      },
      tooltip: {
        formatter: (param) => {
          return ['Cancer: ' + param.name, 'Samples: ' + param.data].join(
            '<br/>'
          );
        },
      },
      emphasis: {
        focus: 'self',
      },
      data: data,
      itemStyle: {
        color: color,
      },
    },
  };
};

const mnv_count_settings_generator = (
  name: string,
  xlabel: string,
  data: number[],
  color: 'blue'
) => {
  return {
    ...common_bar_options(xlabel),
    series: {
      id: name,
      type: 'bar',
      colorBy: 'series',
      label: {
        show: false,
        position: 'right',
      },
      tooltip: {
        formatter: (param) => {
          return ['Cancer: ' + param.name, 'MNV: ' + param.data].join('<br/>');
        },
      },
      emphasis: {
        focus: 'self',
      },
      data: data,
      itemStyle: {
        color: color,
      },
    },
  };
};

const qtl_count_settings_generator = (xlabel: string) => {
  let series = [];
  for (let qtlIndex in dataStat.qtl.cis) {
    let seriesItem = {
      name: qtlIndex,
      type: 'bar',
      stack: 'total',
      label: {
        show: false,
      },
      emphasis: {
        focus: 'series',
      },
      tooltip: {
        formatter: (param) => {
          return [
            'Cancer: ' + param.name,
            'QTL type: ' + param.seriesName,
            'Cis: ' +
              dataStat.qtl.cis[param.seriesName as qtlType][
                cancerList.indexOf(param.name)
              ],
            'Trans: ' +
              dataStat.qtl.trans[param.seriesName as qtlType][
                cancerList.indexOf(param.name)
              ],
            'All: ' + param.data,
          ].join('<br/>');
        },
      },
      data: [],
    };
    for (let cancerIndex in dataStat.qtl.cis[qtlIndex as qtlType]) {
      let sum_cis_trans =
        dataStat.qtl.cis[qtlIndex as qtlType][cancerIndex] +
        dataStat.qtl.trans[qtlIndex as qtlType][cancerIndex];
      seriesItem.data.push(sum_cis_trans);
    }
    series.push(seriesItem);
  }
  return {
    ...common_bar_options(xlabel),
    legend: {
      // show: false,
      orient: 'vertical',
      top: 'center',
      right: 'right',
    },
    series,
  };
};

const phenotype_count_settings_generator = (xlabel: string) => {
  let series = [];
  for (let qtlIndex in dataStat.pheno) {
    let seriesItem = {
      name: qtlIndex,
      type: 'bar',
      stack: 'total',
      label: {
        show: false,
      },
      emphasis: {
        focus: 'series',
      },
      tooltip: {
        formatter: (param) => {
          return [
            'Cancer: ' + param.name,
            'Phenotype : ' + dataStat.pheno_name[param.seriesName],
            'Count : ' + param.data,
          ].join('<br/>');
        },
      },
      data: [],
    };
    for (let cancerIndex in dataStat.pheno[qtlIndex as qtlType]) {
      seriesItem.data.push(dataStat.pheno[qtlIndex as qtlType][cancerIndex]);
    }
    series.push(seriesItem);
  }
  return {
    ...common_bar_options(xlabel),
    legend: {
      show: false,
      orient: 'horizontal',
      top: 'top',
    },
    series,
  };
};

// 图标或dom的引用
const sampleBarDom = ref<HTMLElement | null>(null);
const mnvBarDom = ref<HTMLElement | null>(null);
const phenoBarDom = ref<HTMLElement | null>(null);
const qtlBarDom = ref<HTMLElement | null>(null);

const sampleBarRef = ref<echarts.ECharts | null>(null);
const mnvBarRef = ref<echarts.ECharts | null>(null);
const phenoBarRef = ref<echarts.ECharts | null>(null);
const qtlBarRef = ref<echarts.ECharts | null>(null);

// 初始化函数
const echart_init = (
  chartRef: echarts.ECharts | null,
  domRef: HTMLDivElement | null,
  chartOption
) => {
  echarts.dispose(domRef as HTMLDivElement);
  chartRef = echarts.init(domRef as HTMLDivElement, echart_theme.value, {
    locale: siteSettingRef.language.value,
  });
  chartRef?.setOption(chartOption);
  return chartRef;
};

const resizeHandler = () => {
  sampleBarRef.value?.resize();
  mnvBarRef.value?.resize();
  qtlBarRef.value?.resize();
};

watch(siteSettingRef.dark, () => {
  sampleBarRef.value = echart_init(
    sampleBarRef.value,
    sampleBarDom.value,
    sample_count_settings_generator('smaple', 'Samples', dataStat.sample)
  );
  sampleBarRef.value.group = 'groupBar';

  mnvBarRef.value = echart_init(
    mnvBarRef.value,
    mnvBarDom.value,
    mnv_count_settings_generator('mnv', 'MNVs', dataStat.mnv)
  );
  mnvBarRef.value.group = 'groupBar';

  qtlBarRef.value = echart_init(
    qtlBarRef.value,
    qtlBarDom.value,
    qtl_count_settings_generator('QTLs')
  );
  qtlBarRef.value.group = 'groupBar';

  phenoBarRef.value = echart_init(
    phenoBarRef.value,
    phenoBarDom.value,
    phenotype_count_settings_generator('Phenotypes')
  );
  phenoBarRef.value.group = 'groupBar';

  echarts.connect('groupBar');
  window.addEventListener('resize', resizeHandler);
});

watch(siteSettingRef.language, () => {
  sampleBarRef.value = echart_init(
    sampleBarRef.value,
    sampleBarDom.value,
    sample_count_settings_generator('smaple', 'Samples', dataStat.sample)
  );
  sampleBarRef.value.group = 'groupBar';

  mnvBarRef.value = echart_init(
    mnvBarRef.value,
    mnvBarDom.value,
    mnv_count_settings_generator('mnv', 'MNVs', dataStat.mnv)
  );
  mnvBarRef.value.group = 'groupBar';

  qtlBarRef.value = echart_init(
    qtlBarRef.value,
    qtlBarDom.value,
    qtl_count_settings_generator('QTLs')
  );
  qtlBarRef.value.group = 'groupBar';

  phenoBarRef.value = echart_init(
    phenoBarRef.value,
    phenoBarDom.value,
    phenotype_count_settings_generator('Phenotypes')
  );
  phenoBarRef.value.group = 'groupBar';

  echarts.connect('groupBar');
  window.addEventListener('resize', resizeHandler);
});

onMounted(() => {
  sampleBarRef.value = echart_init(
    sampleBarRef.value,
    sampleBarDom.value,
    sample_count_settings_generator('smaple', 'Samples', dataStat.sample)
  );
  sampleBarRef.value.group = 'groupBar';

  mnvBarRef.value = echart_init(
    mnvBarRef.value,
    mnvBarDom.value,
    mnv_count_settings_generator('mnv', 'MNVs', dataStat.mnv, '#56deb2')
  );
  mnvBarRef.value.group = 'groupBar';

  qtlBarRef.value = echart_init(
    qtlBarRef.value,
    qtlBarDom.value,
    qtl_count_settings_generator('QTLs')
  );
  qtlBarRef.value.group = 'groupBar';

  phenoBarRef.value = echart_init(
    phenoBarRef.value,
    phenoBarDom.value,
    phenotype_count_settings_generator('Phenotypes')
  );
  phenoBarRef.value.group = 'groupBar';

  echarts.connect('groupBar');
  window.addEventListener('resize', resizeHandler);
});
</script>

<style lang="scss">
#BodyMap {
  height: inherit;
  width: inherit;
}
</style>
